package cn.melonlib.cores.aop.comp.url;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.melonlib.cores.aop.anno.IgnorePrepend;
import cn.melonlib.cores.aop.anno.PrependUrl;
import cn.melonlib.cores.aop.comp.web.WebInfo;
import cn.melonlib.cores.commons.comp.utils.UriPathUtils;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.List;
import java.util.regex.Pattern;

@Component
public class PrependUrlInterceptor implements MethodInterceptor {

    @Resource
    @Lazy
    private WebInfo webinfo;

    @Resource
    private UriPathUtils uriPathUtils;

    @Nullable
    @Override
    public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
        Class cls= AopUtils.getTargetClass(invocation.getThis());
        IgnorePrepend ignorePrepend=AnnotationUtils.findAnnotation(invocation.getMethod(), IgnorePrepend.class);
        if(ignorePrepend==null&&invocation.getMethod().getName().startsWith("get")){
            Field field= ReflectUtil.getField(cls, StrUtil.removePreAndLowerFirst(invocation.getMethod().getName(),"get"));
            if(field!=null) {
                ignorePrepend = AnnotationUtils.findAnnotation(field, IgnorePrepend.class);
            }
        }
        if(ignorePrepend!=null){
            return invocation.proceed();
        }

        if(CharSequence.class.isAssignableFrom(invocation.getMethod().getReturnType())){
            String url=invocation.proceed().toString();
            return uriPathUtils.getHttpAbsolutePath(url);
        }else{
            return invocation.proceed();
        }

    }
}
